package com.test.routerplugin;

import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_SUPER;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static org.objectweb.asm.Opcodes.RETURN;
import static org.objectweb.asm.Opcodes.V11;

import com.android.build.gradle.BaseExtension;

import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;

import java.io.FileOutputStream;

/**
 * *******************************************************
 * Author: chinadragon
 * Time: 2023/8/15 10:01
 * Name:
 * Overview:
 * Usage:
 * *******************************************************
 */
//groovy 和 java 代码相通
public class ASMPlugin implements Plugin<Project> {
    @Override
    public void apply(Project target) {//相当于 main 函数
        System.out.println("执行 ASMPlugin 任务");
        target.getExtensions().getByType(BaseExtension.class).registerTransform(new com.test.routerplugin.ASMTransform(target));

        //1.生成Class字节码
/*        byte[] genClassByte = genClass();
        try {
//输出Class字节码文件
            FileOutputStream fos = new FileOutputStream("app/src/main/java/com/example/testcompont/User.class");
            System.out.println("----------- 写入完毕 ");
            fos.write(genClassByte);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }*/
    }

    /*
        字节码操作工具ASM API使用大全
        https://blog.csdn.net/wumeixinjiazu/article/details/125014568

        Android编译时技术（二）ASM 基础使用之代码生成
        https://blog.csdn.net/wumeixinjiazu/article/details/124987533
     */

    public static byte[] genClass() {
        ClassWriter classWriter = new ClassWriter(0);
        classWriter.visit(V11, ACC_PUBLIC | ACC_SUPER, "com.example.testcompont/User", null, "java/lang/Object", null);

        MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        methodVisitor.visitCode();
        //        javac 的帮助 this  为了能够用    this
        Label label0 = new Label();
        methodVisitor.visitLabel(label0);
        methodVisitor.visitLineNumber(3, label0);
        methodVisitor.visitVarInsn(ALOAD, 0);
        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object",
                "<init>", "()V", false);
        methodVisitor.visitInsn(RETURN);
        Label label1 = new Label();
        methodVisitor.visitLabel(label1);
        methodVisitor.visitLocalVariable("this", "Lasm/User;", null, label0,
                label1, 0);
        methodVisitor.visitMaxs(1, 1);
        methodVisitor.visitEnd();
//        java进阶   jvm 虚拟机   深
        classWriter.visitEnd();
        System.out.println("------------  生成字节码完毕");
        return classWriter.toByteArray();
    }
}

